/**                                   
 */
package com.mdcorbri.helicoptobot.mediators
{
	
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	
	import mx.core.UIComponent;
	import mx.events.DynamicEvent;
	import mx.events.FlexEvent;
	
	
	/**
	 * The base class for all view mediators. It's most useful function is to
	 * provide the metadata and setter method t inject the view into the mediator.
	 * 
	 * <p>
	 * In addition, it allows concrete ViewMediators to add view event handlers 
	 * and data bindings to children of the corresponding View with confidence by 
	 * by determining if the view is "alive" or if it needs to listen for it's
	 * creation complete event before performing actions on it. See the 
	 * <code>public function set view( value:* ):void</code> method for more 
	 * details on this.
	 * </p>
	 */
	public class AbstractViewMediator
	{
		/**
		 * Logger.
		 */
		
		/**
		 * Allows this class to dispatch events.
		 */
		public var eventDispatcher:IEventDispatcher;
		
		/**
		 * Constructor.
		 */
		public function AbstractViewMediator()
		{
			super();
		}
		
		/**
		 * Backing variable for <code>view</code> setter.
		 */
		protected var _view:UIComponent;
		
		
		/**
		 * Providing view="true" in the [Autowire] tag tells Swiz
		 * the item to inject will be a view rather than a bean.
		 * In response to the injectionEvent specified in SwizConfig,
		 * Swiz will inject the view into this setter.
		 */
		[Autowire( view="true" )]
		public function set view( value:* ):void
		{
			this._view = value;
			
			// determine if the view has been initialized...
			// NO...listen for it;s creation complete event
			if(this._view.initialized == false)
			{
				this._view.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
			}
			// YES...call the init() method to kick off the instation of the view mediator
			else
			{
				this.init();
			}
			
			// don't get in GC's way if the view is removed
			this._view.addEventListener(Event.REMOVED_FROM_STAGE, cleanup);
		}
		
		/**
		 * The <code>init()</code> method is only called when the ViewMediator corresponding 
		 * View's creationComplete has been fired; this allows developers to add event listens,
		 * data bindings, and any other view functions in confidence (without worry about accessing
		 * children of the view that are null and cause runtime errors.)
		 * 
		 * <p>
		 * Developers can override this to perform additional initializaitons in their ViewMediator,
		 * but must call <code>super.init()</code> in order for the aforementioned to function
		 * correctly.
		 * </p>
		 */
		protected function init():void
		{
			this.setViewListeners();
			this.setViewDataBindings();
			this.setViewSecurity();
		}
		
		/**
		 * Set the listeners for the UI components on the stage for the ViewMediator's corresponding View.
		 */
		protected function setViewListeners():void
		{
			// OVERRIDDEN
		}
		
		/**
		 * Set the data bindings for the UI components on the stage for the ViewMediator's corresponding View.
		 */
		protected function setViewDataBindings():void
		{
			// OVERRIDDEN
		}
		
		/**
		 * Set the security for the UI components on the stage for the ViewMediator's corresponding View.
		 */
		protected function setViewSecurity():void
		{
			// OVERRIDDEN
		}
		
		/**
		 * Set the native AIR functionality.
		 */
		protected function setNativeAIRFunctionality():void
		{
			// OVERRIDDEN
		}
		
		/**
		 * Listen for the creation complete of the View for this ViewMediator.
		 */
		protected function onCreationComplete( event:FlexEvent ):void
		{
			this._view.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
			this.init();
		}
		
		/**
		 * Remove any listeners we've created.
		 * 
		 * <p>
		 * Developers should override this method to remove any custom listners
		 * created in the concrete ViewMediator. Developers must call 
		 * <code>super.cleanup()</code> in order for this to function correctly.
		 * </p>
		 */
		protected function cleanup( event:Event ):void
		{
			this._view.removeEventListener(Event.REMOVED_FROM_STAGE, cleanup);
		}
	}
}